#pragma once
#include "FoGGEDef.h"

namespace _FOGGE_
{
	namespace _UTIL_
	{
		class Name
		{
		public:
			Name(void);
			Name(LPCTSTR name);
			Name(const foString& name);
			Name(const Name& name);
			~Name(void);

			static void Finalize();

			// = operator
			void operator = (LPCTSTR name)
			{
				foString strName=name;
				SetName(strName);
			}

			// = operator
			void operator = (Name& name)
			{
				m_ptrString = name.m_ptrString;
				m_uiUniqID = name.m_uiUniqID;
			}

			// = operator
			void operator = (foString& name)
			{
				SetName(name);
			}

			// == operator
			bool operator == (foString& name)
			{
				return ((*m_ptrString)== name);
			}
			// == operator
			bool operator == (const foString& name)
			{
				return ((*m_ptrString)== name);
			}

			// == operator
			bool operator == (LPCTSTR name) 
			{
				return ((*m_ptrString)== name);
			}
			
			// == operator
			bool operator == (const Name& name) const
			{
				return (m_uiUniqID == name.m_uiUniqID);
			}
			// == operator
			bool operator != (const Name& name) const
			{
				return (m_uiUniqID != name.m_uiUniqID);
			}
			// < operator
			bool operator < (const Name& name) const
			{
				return (m_uiUniqID < name.m_uiUniqID);
			}
			// < operator
			bool operator <= (const Name& name) const
			{
				return (m_uiUniqID <= name.m_uiUniqID);
			}
			// < operator
			bool operator > (const Name& name) const
			{
				return (m_uiUniqID > name.m_uiUniqID);
			}
			// > operator
			bool operator >= (const Name& name) const
			{
				return (m_uiUniqID >= name.m_uiUniqID);
			}

			// == operator
			bool operator == (Name& name) const
			{
				return (m_uiUniqID == name.m_uiUniqID);
			}
			// == operator
			bool operator != (Name& name) const
			{
				return (m_uiUniqID != name.m_uiUniqID);
			}
			// < operator
			bool operator < (Name& name) const
			{
				return (m_uiUniqID < name.m_uiUniqID);
			}
			// <= operator
			bool operator <= (Name& name) const
			{
				return (m_uiUniqID <= name.m_uiUniqID);
			}
			// > operator
			bool operator > (Name& name) const
			{
				return (m_uiUniqID > name.m_uiUniqID);
			}
			// >= operator
			bool operator >= (Name& name) const
			{
				return (m_uiUniqID >= name.m_uiUniqID);
			}

			
			const TCHAR * c_str () const;
			const char * Name::c_strAnsi(); 
		private:
			
			void CheckName(foString& name,HashMap<foString,foUInt>::iterator& iterResult);

			void SetName(const foString& name);

			const foString* m_ptrString;

			foUInt m_uiUniqID;

			static HashMap<foString,foUInt>* s_ptrmapString;
			
		};
		
	}
	extern _UTIL_::Name Name_None;
}

#define FoDeclareRegisterName(NameToRegister)\
	extern ::_FOGGE_::_UTIL_::Name Name_##NameToRegister

#define FoImplementRegisterName(NameToRegister)\
	::_FOGGE_::_UTIL_::Name Name_##NameToRegister(__T(#NameToRegister))

